package top.chmin.project.cloud.sys.column.info;

import cn.hutool.json.JSONUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import top.chmin.project.cloud.common.BasePlugin;
import top.chmin.project.cloud.common.Page;
import top.chmin.project.cloud.sys.table.info.TableInfo;
import top.chmin.project.cloud.sys.table.info.TableInfoCondition;
import top.chmin.project.cloud.tool.DatetimeTool;


/**
 * chmin
 * 2024-01-25 14:22:04
 * cloud-code
 */
@Slf4j
@Component
public class ColumnInfoPlugin extends BasePlugin {

    @Resource
    JdbcTemplate template;

    public void checkSave(ColumnInfoSaveRest.P p) {
        log.debug("checkSave-p: {}", JSONUtil.toJsonStr(p));
        if (p == null) {
            throw new RuntimeException("保存对象不能为空");
        }
    }

    public void beforeSave(ColumnInfo columnInfo) {
        log.debug("beforeSave-columnInfo: {}", JSONUtil.toJsonStr(columnInfo));
        /* append $pluginCodeAppender$ */

        switch (columnInfo.getColumnType()) {
            case "int", "bigint": {
                columnInfo.setColumnLength(0);
                columnInfo.setColumnPrecision(0);
                columnInfo.setColumnScale(0);
                break;
            }
            case "decimal": {
                if (columnInfo.getColumnScale() == null) {
                    columnInfo.setColumnScale(2);
                }
                if (columnInfo.getColumnPrecision() == null) {
                    columnInfo.setColumnPrecision(10);
                }
                columnInfo.setColumnLength(0);
                break;
            }
            case "datetime": {
                break;
            }
            default: {
                if (columnInfo.getColumnLength() == null) {
                    columnInfo.setColumnLength(32);
                }
                columnInfo.setColumnPrecision(0);
                columnInfo.setColumnScale(0);
                break;
            }
        }

    }

    public void afterSave(ColumnInfoSaveRest.P p, ColumnInfo columnInfo, int result) {
        log.debug("afterSave-p: {}", JSONUtil.toJsonStr(p));
        log.debug("afterSave-columnInfo: {}", JSONUtil.toJsonStr(columnInfo));
        log.debug("afterSave-result: {}", JSONUtil.toJsonStr(result));

        TableInfo tableInfo = TableInfoCondition.selectByTableCode(columnInfo.getTableCode());

        switch (columnInfo.getColumnType()) {
            case "varchar", "char": {
                template.execute("ALTER TABLE %s ADD COLUMN %s VARCHAR(%s) %s COMMENT '%s';".formatted(
                        tableInfo.getTableName(),
                        columnInfo.getColumnName(),
                        columnInfo.getColumnLength(),
                        "Y".equals(columnInfo.getColumnNullable()) ? "NULL" : "NOT NULL",
                        columnInfo.getColumnComment())
                );
                break;
            }
            case "DECIMAL": {
                template.execute("ALTER TABLE %s ADD COLUMN %s DECIMAL(%s, %s) %s COMMENT '%s';".formatted(
                        tableInfo.getTableName(),
                        columnInfo.getColumnName(),
                        columnInfo.getColumnPrecision(),
                        columnInfo.getColumnScale(),
                        "Y".equals(columnInfo.getColumnNullable()) ? "NULL" : "NOT NULL",
                        columnInfo.getColumnComment())
                );
                break;
            }
            default: {
                template.execute("ALTER TABLE %s ADD COLUMN %s %s %s COMMENT '%s';".formatted(
                        tableInfo.getTableName(),
                        columnInfo.getColumnName(),
                        columnInfo.getColumnType(),
                        "Y".equals(columnInfo.getColumnNullable()) ? "NULL" : "NOT NULL",
                        columnInfo.getColumnComment())
                );
            }
        }
    }

    public void checkUpdate(ColumnInfoUpdateRest.P p) {
        log.debug("checkUpdate-p: {}", JSONUtil.toJsonStr(p));
        if (p == null) {
            throw new RuntimeException("更新对象不能为空");
        }
        if (p.getId() == null) {
            throw new RuntimeException("更新对象id不能为空");
        }
    }

    public void beforeUpdate(ColumnInfo columnInfo) {
        log.debug("beforeUpdate-columnInfo: {}", JSONUtil.toJsonStr(columnInfo));

    }

    public void afterUpdate(ColumnInfoUpdateRest.P p, ColumnInfo columnInfo, int result) {
        log.debug("afterUpdate-p: {}", JSONUtil.toJsonStr(p));
        log.debug("afterUpdate-columnInfo: {}", JSONUtil.toJsonStr(columnInfo));
        log.debug("afterUpdate-result: {}", JSONUtil.toJsonStr(result));

    }

    public void checkDelete(ColumnInfoDeleteRest.P p) {
        log.debug("checkDelete-p: {}", JSONUtil.toJsonStr(p));
        if (p == null) {
            throw new RuntimeException("删除对象不能为空");
        }
        if (p.getId() == null) {
            throw new RuntimeException("删除对象id不能为空");
        }
    }

    public void beforeDelete(ColumnInfo columnInfo) {
        log.debug("beforeDelete-columnInfo: {}", JSONUtil.toJsonStr(columnInfo));

    }

    public void afterDelete(ColumnInfoDeleteRest.P p, ColumnInfo columnInfo, int result) {
        log.debug("afterDelete-p: {}", JSONUtil.toJsonStr(p));
        log.debug("afterDelete-columnInfo: {}", JSONUtil.toJsonStr(columnInfo));
        log.debug("afterDelete-result: {}", JSONUtil.toJsonStr(result));

    }

    public void checkSelect(ColumnInfoSelectRest.P p) {
        log.debug("checkSelect-p: {}", JSONUtil.toJsonStr(p));
        if (p == null) {
            throw new RuntimeException("查询对象不能为空");
        }
        if (p.getId() == null) {
            throw new RuntimeException("查询对象id不能为空");
        }
    }

    public void beforeSelect(ColumnInfoSelectRest.P p, ColumnInfoCondition c) {
        log.debug("beforeSelect-p: {}", JSONUtil.toJsonStr(p));
        log.debug("beforeSelect-c: {}", JSONUtil.toJsonStr(c));

    }

    public void afterSelect(ColumnInfoSelectRest.P p, ColumnInfoSelectRest.R r) {
        log.debug("afterSelect-p: {}", JSONUtil.toJsonStr(p));
        log.debug("afterSelect-result: {}", JSONUtil.toJsonStr(r));

    }

    public void checkPage(ColumnInfoPageRest.P p) {
        log.debug("checkPage-p: {}", JSONUtil.toJsonStr(p));
        if (p == null) {
            throw new RuntimeException("分页对象不能为空");
        }
    }

    public void beforePage(ColumnInfoPageRest.P p, ColumnInfoCondition c) {
        log.debug("beforePage-p: {}", JSONUtil.toJsonStr(p));
        log.debug("beforePage-c: {}", JSONUtil.toJsonStr(c));

        /*###########auto#start###########*/
        c.columnCode().eq(p.getColumnCode());
        c.columnComment().eq(p.getColumnComment());
        c.columnDict().eq(p.getColumnDict());
        c.columnLabel().eq(p.getColumnLabel());
        c.columnLength().eq(p.getColumnLength());
        c.columnName().eq(p.getColumnName());
        c.columnNullable().eq(p.getColumnNullable());
        c.columnPrecision().eq(p.getColumnPrecision());
        c.columnRelate().eq(p.getColumnRelate());
        c.columnScale().eq(p.getColumnScale());
        c.columnSequence().eq(p.getColumnSequence());
        c.columnType().eq(p.getColumnType());
        c.createBy().eq(p.getCreateBy());
        c.createTime().ge(p.getCreateTime() == null || p.getCreateTime().length == 0 ? null : p.getCreateTime()[0]);
        c.createTime().lt(p.getCreateTime() == null || p.getCreateTime().length < 2 ? null : DatetimeTool.nextDay(p.getCreateTime()[1]));
        c.tableCode().eq(p.getTableCode());
        c.updateBy().eq(p.getUpdateBy());
        c.updateTime().ge(p.getUpdateTime() == null || p.getUpdateTime().length == 0 ? null : p.getUpdateTime()[0]);
        c.updateTime().lt(p.getUpdateTime() == null || p.getUpdateTime().length < 2 ? null : DatetimeTool.nextDay(p.getUpdateTime()[1]));
        /*###########auto##end############*/
        /* append $pluginBeforePageAppender$ */

    }

    public void afterPage(ColumnInfoPageRest.P p, Page<ColumnInfoPageRest.R> r) {
        log.debug("afterPage-p: {}", JSONUtil.toJsonStr(p));
        log.debug("afterPage-result: {}", JSONUtil.toJsonStr(r));

    }

    /* append $pluginSelectOptionMethodAppender$ */
}
